package cn.seaboot.flake.jdbc;

import cn.seaboot.commons.reflect.FieldAccess;
import cn.seaboot.commons.reflect.ObjectField;
import org.jetbrains.annotations.NotNull;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;

import javax.persistence.Column;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 将查询到的数据打包成对象
 * <p>
 * 从 JPA 注解中，获取字段映射信息，将查询结果封装成指定的对象
 *
 * @author Mr.css
 * @version 2020-11-15 10:41
 */
public class JPAObjectResultSetExtractor<T> implements ResultSetExtractor<List<T>> {

    /**
     * 需要转换的 VO 类型
     */
    private final Class<T> clazz;

    /**
     * -
     *
     * @param clazz 目标类型
     */
    public JPAObjectResultSetExtractor(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public List<T> extractData(@NotNull ResultSet rs) throws SQLException, DataAccessException {
        FieldAccess access = FieldAccess.create(clazz);

        Map<String, String> mapping = new HashMap<>();
        for (ObjectField field : access.getFields()) {
            Column column = field.getAnnotation(Column.class);
            if (column != null) {
                mapping.put(column.name(), field.getName());
            } else {
                mapping.put(field.getName(), field.getName());
            }
        }

        return JdbcUtils.toObject(rs, access, mapping);
    }
}
